﻿using System;
using System.Collections.Generic;
using UnityEngine.Events;

#region 骚操作,用于躲避拆箱装箱
public interface IEventInfo
{

}
public class EventInfo<T> : IEventInfo
{
    public Action<T> action;

    public EventInfo(Action<T> _action)
    {
        action = _action;
    }
}

public class EventInfo : IEventInfo
{
    public Action action;

    public EventInfo(Action _action)
    {
        action = _action;
    }
}
#endregion

/// <summary>
/// 事件管理器, 用于总控事件(观察者设计模式)
/// 使用方法: 监听事件记得添加移出监听接口 触发事件即可
/// </summary>
public class EventManager : Singleton<EventManager>
{
    private Dictionary<string, IEventInfo> eventDic = new Dictionary<string, IEventInfo>();

    #region 无参事件
    public void AddEventListener(string eventName, Action action)
    {
        if (eventDic.ContainsKey(eventName))
        {
            (eventDic[eventName] as EventInfo).action += action; // 父类强转子类 然后就可以不用object装箱拆箱
        }
        else
        {
            eventDic.Add(eventName, new EventInfo(action));
        }
    }

    public void RemoveEventListener(string eventName, Action action)
    {
        if (eventDic.ContainsKey(eventName))
        {
            (eventDic[eventName] as EventInfo).action -= action;
        }
    }

    public void EventTrigger(string eventName)
    {
        if (eventDic.ContainsKey(eventName))
        {
            (eventDic[eventName] as EventInfo).action?.Invoke();
        }
    }

    #endregion

    #region 单个传递参数事件
    public void AddEventListener<T>(string eventName, Action<T> action)
    {
        if (eventDic.ContainsKey(eventName))
        {
            //注: 不能同一个事件名 不同类型的参数
            (eventDic[eventName] as EventInfo<T>).action += action; // 父类强转子类 然后就可以不用object装箱拆箱 

        }
        else
        {
            eventDic.Add(eventName, new EventInfo<T>(action));
        }
    }

    public void RemoveEventListener<T>(string eventName, Action<T> action)
    {
        if (eventDic.ContainsKey(eventName))
        {
            (eventDic[eventName] as EventInfo<T>).action -= action;
        }
    }

    public void EventTrigger<T>(string eventName, T message)
    {
        if (eventDic.ContainsKey(eventName))
        {
            (eventDic[eventName] as EventInfo<T>).action?.Invoke(message);
        }
    }
    #endregion

    public void Clear()
    {
        eventDic.Clear();
    }
}


